import math
import app.algorithm.sma as SMA
import pandas as pd
import re
from functools import reduce

class Algorithm(object):

    def __init__(self, stroe, root):
        self._stroe = stroe
        self._market = root
        
    def _analysis(self, code):

        try:
            all_data = self._load_company_data(code)
            if all_data:
            
                sorted_years = sorted(all_data.keys(), reverse=False)
                merged_data = reduce(lambda acc, year: {'date': acc['date'] + all_data[year]['date'], 
                                                        'close': acc['close'] + all_data[year]['close'],
                                                        'volume': acc['volume'] + all_data[year]['volume'],
                                                        'open': acc['open'] + all_data[year]['open'],
                                                        'high': acc['high'] + all_data[year]['high'],
                                                        'low': acc['low'] + all_data[year]['low']
                                                        }, sorted_years, 
                                                        {'date': [], 'close': [], 'volume': [], 'open': [], 'high': [], 'low': []})
                close = merged_data['close']
                #df = pd.DataFrame(close)

                result = {}
                result['date'] = merged_data['date']
                #days = len(result['date'])
                result['sma6'] = SMA.SMA_Rolling(close, 6)

                #print("sma6: ", result['sma6'].values.tolist())
                result['sma13'] = SMA.SMA_Rolling(close, 13)

                self._save_analysis_data(code, sorted_years, result)
            else:
                print("analysis: {} load empty.".format(code))
        except Exception as ex:
            raise ConnectionError("app start algorithm exception", ex)

    def _get_year_by_name(self, name):
        match = re.search(r'(\d{4})', name)
        if match:
            return match.group(1)
        else:
            return "2019"

    def _load_company_data(self, code):

        key = "{}/{}/history-{}-".format(self._market, code,code)

        all_data = {}
        every_year_list = self._stroe.load_list(key)
        for every_year in every_year_list:
            year_data = self._stroe.load(every_year.object_name)
            if year_data:
                if year_data['date'] and len(year_data['date']) > 0:
                    name = year_data['date'][0]
                    year = self._get_year_by_name(name)
                    all_data[year] = year_data

        return all_data
    
    def _save_analysis_data(self, code, years, result):

        filtered_data = {}

        for year in years:
            filtered_data[year] = { 'sma6': [], 'sma13': []}

        for index, date in enumerate(result['date']):
            year = self._get_year_by_name(date)
            if year in years:
                sma6 = round(float(result['sma6'][index]), 3)
                sma13 = round(float(result['sma13'][index]), 3)
                if math.isnan(sma6):
                    sma6 = 0
                if math.isnan(sma13):
                    sma13 = 0
                filtered_data[year]['sma6'].append(sma6)
                filtered_data[year]['sma13'].append(sma13)

        
        for year in filtered_data:
            self._stroe.save(code, year,  filtered_data[year])


